package pl.jtb.ctl.tabory.ui.boe.ui.ve;

import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.Section;

import pl.jtb.ctl.tabory.dao.api.services.ICompositionService;
import pl.jtb.ctl.tabory.dao.api.services.IVagonService;
import pl.jtb.ctl.tabory.dao.data.vo.CompositionVO;
import pl.jtb.ctl.tabory.dao.data.vo.VagonVO;
import pl.jtb.ctl.tabory.dao.impl.mybatis.servicemanager.ServiceManager;
import pl.jtb.ctl.tabory.ui.boe.osgi.Activator;
import pl.jtb.ctl.tabory.ui.boe.selection.VagonSelection;
import pl.jtb.ctl.tabory.ui.editors.AbstractMasterDetailSection;
import pl.jtb.ctl.tabory.ui.editors.EditorStateSL;
import pl.jtb.ctl.tabory.ui.selection.ISelectionListener;

public class VagonEditor extends AbstractMasterDetailSection<VagonSelection, VagonMasterSectionPart, VagonDetailSectionPart> {

    public static final String ID = "pl.jtb.ctl.tabory.ui.boe.ui.ve.VagonEditor";

    private final static Logger log = Logger.getLogger(VagonEditor.class);

    public VagonEditor() throws Exception {
        super();
    }

    @Override
    protected VagonMasterSectionPart getMasterSection(Form parentForm) {
        Set<VagonMasterSectionPart.AvailableColumnsSL> setAllColumns = new HashSet<VagonMasterSectionPart.AvailableColumnsSL>();
        setAllColumns.add(VagonMasterSectionPart.AvailableColumnsSL.COLUMN_COMPOSITION_NAME);
        setAllColumns.add(VagonMasterSectionPart.AvailableColumnsSL.COLUMN_VAGON_NAME);
        setAllColumns.add(VagonMasterSectionPart.AvailableColumnsSL.COLUMN_DISTANCE_CORRECTED);
        VagonMasterSectionPart sectionPart = new VagonMasterSectionPart(parentForm.getBody(), formToolkit, Section.TITLE_BAR, Activator.getMessage("vagons.editor.table.title"), true, true, setAllColumns);
        sectionPart.setSelection(selection);
        return sectionPart;
    }

    @Override
    protected VagonDetailSectionPart getDetailSection(Form parentForm) {
        VagonDetailSectionPart sectionPart = new VagonDetailSectionPart(parentForm.getBody(), formToolkit, Section.TITLE_BAR, Activator.getMessage("vagons.editor.details"));
        sectionPart.setSelection(selection);
        return sectionPart;
    }

    @Override
    protected void postInitGui(Composite parent) {
        masterSectionPart.addSelectionListener(new ISelectionListener<VagonSelection>() {
            @Override
            public void selectionChanged(final VagonSelection selection) {
                log.debug("Selection changed.");
                BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
                    @Override
                    public void run() {
                        EditorStateSL editorStateSL = selection.getEditorState();
                        if (editorStateSL.equals(EditorStateSL.CLEAN)) {
                            setDirty(false);
                        } else {
                            setDirty(true);
                        }
                        masterSectionPart.setSelection(selection);
                        detailSectionPart.setSelection(selection);
                    }
                });
            }
        });
    }

    @Override
    protected void doSave() throws Exception {
        IVagonService vagonService = ServiceManager.getInstance().getVagonService();
        VagonSelection saveSelection = detailSectionPart.getSelection();
        VagonVO selectedVagon = saveSelection.getSelectedVagon();
        if (selectedVagon.getId() == null) {
            VagonVO vagon = vagonService.getVagon(selectedVagon.getInternalId());
            if (vagon != null) {
                MessageDialog.openError(getSite().getShell(), Activator.getMessage("vagons.validation.save.notunique.title"), Activator.getMessage("vagons.validation.save.notunique.message"));
                return;
            }
        }
        vagonService.saveUpdateVagon(selectedVagon);
        selection = initSelection();
        masterSectionPart.setSelection(selection);
        detailSectionPart.setSelection(selection);
        setDirty(false);
    }

    @Override
    protected void doCancel() throws Exception {
        selection = initSelection();
        masterSectionPart.setSelection(selection);
        detailSectionPart.setSelection(selection);
        setDirty(false);
    }

    @Override
    protected VagonSelection initSelection() throws Exception {
        log.debug("Creating VagonSelection.");
        IVagonService vagonService = ServiceManager.getInstance().getVagonService();
        ICompositionService compositionService = ServiceManager.getInstance().getCompositionService();
        VagonSelection selection = new VagonSelection();
        List<VagonVO> allVagons = vagonService.getListAllVagons();
        List<CompositionVO> listAllCompositions = compositionService.getListAllCompositions();
        Map<CompositionVO, List<VagonVO>> mapRelation = new LinkedHashMap<CompositionVO, List<VagonVO>>();
        for (CompositionVO composition : listAllCompositions) {
            mapRelation.putAll(compositionService.getCompositionVagonRelation(composition));
        }
        selection.setMapCompositionVagons(mapRelation);
        selection.setListVagons(allVagons);
        selection.setListCompositions(listAllCompositions);
        selection.setEditorState(EditorStateSL.CLEAN);
        log.debug("VagonSelection created: " + selection);
        return selection;
    }

    @Override
    public void setFocus() {
        setDirty(true);
        editorCancelAction.run();
    }

}
